<?php
/**
 * Created by PhpStorm.
 * User: Shen
 * Date: 2020/03/19
 * Time: 17:33
 */
namespace app\mini\controller\v1;

use app\common\library\exception\ApiException;
use app\common\library\IAuth;
use app\common\library\MemberVo;
use app\common\model\Member;
use app\common\model\MemberClue;
use app\common\model\RoleUser;
use app\common\model\ShopMember;
use app\job\Clue;
use app\mini\controller\Common;
use EasyWeChat\Factory;
use think\Cache;
use think\Db;
use think\Exception;
use think\Queue;
use Wxcrypt\Wxcrypt;


class Login extends Common
{

    /**
     * 登录
     * @return array
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     */
    public function login()
    {
        $res = $this->transException(function () {
            $code = request()->param('code');
            $clue_token = request()->param('clue_token','');
            $wxConfig = config('wechat');
            $app = Factory::miniProgram($wxConfig);
            $data = $app->auth->session($code);
            if (isset($data['errcode']))
                throw new ApiException($data['errmsg'],404);
            $token = IAuth::setAppLoginToken($data['openid']); //设置登录的token  - 唯一性的
            $member_info = Member::get(['mini_openid'=>$data['openid']]);//获取用户信息
            if (!$member_info){
                $source = !empty($clue_token) ? 1 : 0;
                Member::create(['member_name'=>randomName(),'unionid'=>$data['unionid'] ?? '','mini_openid'=>$data['openid'],'balance'=>0,'source'=>$source]);
                $member_info = Member::get(['mini_openid'=>$data['openid']]);//获取用户信息
                if (!empty($clue_token)){
                    MemberClue::create(['member_id'=>$member_info['id'],'clue_token'=>$clue_token]);
                    Queue::push(Clue::class,['member_id'=>$member_info['id'],'event_type'=>0,'props'=>['is_old_user'=>1]],'message');//激活
                    Queue::push(Clue::class,['member_id'=>$member_info['id'],'event_type'=>1],'message');//注册
                }
            }
            $result = [
                'member_id'=>$member_info['id'],
                'member_mobile'=>$member_info['member_mobile'],
                'member_avatar'=>$member_info['member_avatar'],
                'member_name'=>$member_info['member_name'],
                'mini_openid'=>$member_info['mini_openid'],
                'default_shop_id'=>$member_info['default_shop_id'],
                'token'=>$token,
                'member_type'=>$member_info['member_type'],//member_type当前默认所处的类型 0车主端  1商家端
                'role_id'=>0//role_id角色 0 默认 1管理员 2普通店员
            ];
            if ($member_info['default_shop_id'] >0 && $member_info['member_type'] == 1){
                $result['member_type'] = $member_info['member_type'];//当前默认所处的类型 0用户端  1商家端
                $result['role_id'] = model('shop_member')->where(['shop_id'=>$member_info['default_shop_id'],'member_id'=>$member_info['id']])->value('is_admin') ===1 ? 1 : 2;
//                $result['role_id'] = RoleUser::getRoleIdByCondition(['member_id'=>$member_info['id'],'shop_id'=>$member_info['default_shop_id']]);//获取角色id
            }
            Member::update(['logintime'=>time(),'unionid'=>$data['unionid'] ?? '','login_ip'=>getIPaddress()],['id'=>$member_info['id']]);
            $result['session_key'] = $data['session_key'];
            Cache::store('redis')->set($data['openid'],$data['session_key'],604800); //保存session_key
            Cache::store('redis')->set($token,json_encode($result),604800); //保存用户信息
//            $memberVo = MemberVo::instance();
//            $memberVo->setMemberId($member_info['id']);
//            $memberVo->setMemberType($this->member_info_arr['member_type'] ?? 0);
//            $memberVo->setMiniOpenId($this->member_info_arr['mini_openid'] ?? '');
//            $memberVo->setShopId($this->member_info_arr['default_shop_id'] ?? 0);
//            $memberVo->setToken($this->member_info_arr['token'] ?? '');
            return $result;
        });
        return $this->response($res);
    }


    /**
     * 用户授权
     * @return array
     * @throws \EasyWeChat\Kernel\Exceptions\DecryptException
     */
    public function authorization()
    {
        $token = input('token','');
        $rawData = input('rawData','','htmlspecialchars_decode');//不包括敏感信息的原始数据字符串，用于计算签名
        $signature = input('signature','','htmlspecialchars_decode');//使用 sha1( rawData + sessionkey ) 得到字符串，用于校验用户信息
        $encryptedData = input('encryptedData','','htmlspecialchars_decode');//包括敏感数据在内的完整用户信息的加密数据
        $iv = input('iv','','htmlspecialchars_decode');//加密算法的初始向量
        Db::startTrans(); //开启事务
        try{
            if (empty($rawData) || empty($signature)|| empty($encryptedData) || empty($iv)){
                throw new Exception('参数不全');
            }
            $member_info = $this->member_info_arr;
            $session_key = Cache::get($member_info['mini_openid']);
            $wxConfig = config('wechat');
            $app = Factory::miniProgram($wxConfig);
            $authData = $app->encryptor->decryptData($session_key, $iv, $encryptedData);
            if (isset($authData['errcode'])) {
                self::$http_code = 200;
                throw new Exception($authData['errmsg'],200);
            }
            $session_key = $authData['session_key'];
            $signature2 = sha1($rawData.$session_key);
            if ($signature2 !== $signature){
                self::$http_code = 200;
                throw new Exception("signNotMatch");
            }
            $pc = new Wxcrypt($wxConfig['mini_program']['app_id'],$session_key);
            $errCode = $pc->decryptData($encryptedData,$iv,$data);
            if ($errCode !== 0) {
                self::$http_code = 200;
                throw new Exception("encryptDataNotMatch");
            }
            $data = json_decode($data,true);
            // 验证重复授权
            $info = Member::where(['mini_openid'=>$data['openId']])->find();
            if (!empty($info)){
                self::$http_code = 200;
                throw new Exception("用户已经授权过了，无需再授权");
            }
            // 新增用户信息
            $member_id = Member::addMember($data);
            $memberInfo = ['member_id'=>$member_id, 'member_mobile'=>'', 'member_avatar'=>$data['avatarUrl'], 'member_name'=>$data['nickName'], 'mini_openid'=>$data['openId'], 'default_shop_id'=>0, 'token'=>$token, 'member_type'=>0,'role_id'=>0];
            Cache::store('redis')->set('member_token_'.$member_id,$token,604800); //token缓存
            Cache::store('redis')->rm($token);
            Cache::store('redis')->set($token,json_encode($memberInfo),604800); //保存用户信息
            Db::commit(); //事务提交
            return show(200, 'success', $memberInfo);
        }catch (Exception $e){
            Db::rollback(); //回滚
            return show($e->getCode(), $e->getMessage(), [], self::$http_code);
        }
    }




    /**
     * 授权获取手机号
     */
    public function authorization_phone()
    {
        $res = $this->transException(function () {
            $params = request()->param();
            $member_info = $this->member_info_arr;
            $wxConfig = config('wechat');
            $app = Factory::miniProgram($wxConfig);
            $data = $app->phone_number->getUserPhoneNumber($params['code']);
            if ($data['errcode'] !== 0)
                throw new ApiException('获取手机号失败，请重试',404);
            $result = Member::get(['member_mobile'=>$data['phone_info']['phoneNumber']]);
            if ($result){
                if ($result['id'] != $member_info['member_id'])
                    throw new ApiException("该手机号已经被其他账号绑定了",404);
                return $member_info;
            }
            Member::update(['member_mobile'=>$data['phone_info']['phoneNumber']],['id'=>$member_info['member_id']]);
            $member_info['member_mobile'] = $data['phone_info']['phoneNumber'];
            Cache::store('redis')->set($params['token'],json_encode($member_info),604800); //保存用户信息
            return $member_info;
        });
        return $this->response($res);
    }










}